/*******************************************************************************
 * @(#)MongoDBDaoImpl.java 2016年8月17日
 *
 * Copyright 2016 emrubik Group Ltd. All rights reserved.
 * EMRubik PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *******************************************************************************/
package com.emrubik.mongod.DaoFactory;

import java.util.ArrayList;
import java.util.Map;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.mongodb.WriteResult;
import com.mongodb.util.JSON;

/**
 * 数据库操作类
 * @author <a href="mailto:wangjh@emrubik.com">wangjh</a>
 * @version $Revision 1.0 $ 2016年8月17日 下午7:07:28
 */
public class MongoDBDaoImpl {
    
    private MongoClient mongoClient = null;

    private static final MongoDBDaoImpl mongoDBDaoImpl = new MongoDBDaoImpl();// 饿汉式单例模式

    private MongoDBDaoImpl() {
        if (mongoClient == null) {
            MongoClientOptions.Builder builde = new MongoClientOptions.Builder();
            builde.connectionsPerHost(100);// 与目标数据库可以建立的最大链接数
            builde.connectTimeout(1000 * 60 * 20);// 与数据库建立链接的超时时间
            builde.maxWaitTime(100 * 60 * 5);// 一个线程成功获取到一个可用数据库之前的最大等待时间
            builde.threadsAllowedToBlockForConnectionMultiplier(100);
            builde.maxConnectionIdleTime(0);
            builde.maxConnectionLifeTime(0);
            builde.socketTimeout(0);
            builde.socketKeepAlive(true);
            MongoClientOptions myOptions = builde.build();
            mongoClient = new MongoClient(new ServerAddress("192.168.17.128", 27017), myOptions);
        }
    }

    public static MongoDBDaoImpl getMongoDBDaoImpl() {
        return mongoDBDaoImpl;
    }

    /**
     * 获取数据
     * getDb
     * @param dbName
     * @return
     */
    public DB getDb(String dbName) {
        return mongoClient.getDB(dbName);
    }

    /**
     * 获取集合
     * getCollection
     * @param dbName
     * @param collectionName
     * @return
     */
    public DBCollection getCollection(String dbName, String collectionName) {
        DB db = mongoClient.getDB(dbName);
        return db.getCollection(collectionName);
    }

    /**
     * 插入数据 直接插入json内容
     * inSert
     * @param dbName
     * @param collectionName
     * @param keys
     * @param values
     * @return
     */
    public boolean inSert(String dbName, String collectionName, String json) {
        DB db = mongoClient.getDB(dbName);
        DBCollection dbCollection = db.getCollection(collectionName);
        long num = dbCollection.count();
//        BasicDBObject doc = new BasicDBObject(documentMap);
        DBObject dbObject =(DBObject)JSON.parse(json);
        dbCollection.insert(dbObject);
        if (dbCollection.count() - num > 0) {
            System.out.println("添加数据成功！！！");
            return true;
        }
        return false;
    }

    /**
     * 删除数据
     * delete
     * @param dbName
     * @param collectionName
     * @param keys
     * @param values
     * @return
     */
    public boolean delete(String dbName, String collectionName, String keys, Object values) {
        WriteResult writeResult = null;
        DB db = mongoClient.getDB(dbName);
        DBCollection dbCollection = db.getCollection(collectionName);
        BasicDBObject doc = new BasicDBObject();
        doc.put(keys, values);
        writeResult = dbCollection.remove(doc);
        if (writeResult.getN() > 0) {
            System.out.println("删除数据成功!!!!");
            return true;
        }
        return false;
    }

    /**
     * 查询数据
     * find
     * @param dbName
     * @param collectionName
     * @param num
     * @return
     */
    public ArrayList<DBObject> find(String dbName, String collectionName, int num) {
        int count = num;
        ArrayList<DBObject> list = new ArrayList<DBObject>();
        DB db = mongoClient.getDB(dbName);
        DBCollection dbCollection = db.getCollection(collectionName);
        DBCursor dbCursor = dbCollection.find();
        if (num == -1) {
            while (dbCursor.hasNext()) {
                list.add(dbCursor.next());
            }
        } else {
            while (dbCursor.hasNext()) {
                if (count == 0) break;
                list.add(dbCursor.next());
                count--;
            }
        }
        return list;
    }

    /**
     * 更新数据
     * update
     * @param dbName
     * @param collectionName
     * @param oldValue
     * @param newValue
     * @return
     */
    public boolean update(String dbName, String collectionName, DBObject oldValue,
            DBObject newValue) {
        WriteResult writeResult = null;
        DB db = mongoClient.getDB(dbName);
        DBCollection dbCollection = db.getCollection(collectionName);
        writeResult = dbCollection.update(oldValue, newValue);
        if (writeResult.getN() > 0) {
            System.out.println("数据更新成功");
            return true;
        }
        return false;
    }

    /**
     * 判断是否存在
     * isExit
     * @param dbName
     * @param collectionName
     * @param key
     * @param value
     * @return
     */
    public boolean isExit(String dbName, String collectionName, String key, Object value) {
        DB db = mongoClient.getDB(dbName);
        DBCollection dbCollection = db.getCollection(collectionName);
        BasicDBObject doc = new BasicDBObject();
        doc.put(key, value);
        if (dbCollection.count(doc) > 0) {
            return true;
        }
        return false;
    }

    public static void main(String args[]) {
        MongoDBDaoImpl mongoDBDaoImpl = MongoDBDaoImpl.getMongoDBDaoImpl();
        ArrayList<DBObject> list = new ArrayList<DBObject>();
        list = mongoDBDaoImpl.find("jd", "phone", -1);
        System.out.println(list.size());
    }
}
